package cn.darkhorse.mesmeter.service.impl;

import cn.darkhorse.mesmeter.dto.param.MesMeterElectricityInfoParam;
import cn.darkhorse.mesmeter.mapper.MesMeterElectricityInfoMapper;
import cn.darkhorse.mesmeter.pojo.IotGateway;
import cn.darkhorse.mesmeter.pojo.MesMeter;
import cn.darkhorse.mesmeter.pojo.MesMeterElectricityInfo;
import cn.darkhorse.mesmeter.pojo.MeterTreeItem;
import cn.darkhorse.mesmeter.service.MesMeterElectricityInfoService;
import cn.darkhorse.mesmeter.service.MesMeterService;
import cn.darkhorse.mesmeter.vo.MesMeterElectricityInfoVO;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 用电名称表 服务实现类
 * </p>
 *
 * @author maoguanjun
 * @since 2023-08-29
 */
@Service
public class MesMeterElectricityInfoServiceImpl extends JoinServiceImpl<MesMeterElectricityInfoMapper, MesMeterElectricityInfo> implements MesMeterElectricityInfoService {
    @Resource
    private MesMeterService mesMeterService;
    @Override
    public List<MesMeterElectricityInfo> listAll(MesMeterElectricityInfoParam param){
        LambdaQueryWrapper<MesMeterElectricityInfo> wrapper=new LambdaQueryWrapper<>();
        if(null!=param.getParentId()){
            wrapper.eq(MesMeterElectricityInfo::getParentId,param.getParentId());
        }
        if(null!=param.getElectricityType()){
            wrapper.eq(MesMeterElectricityInfo::getElectricityType,param.getElectricityType());
        }
        return list(wrapper);
    }

    /**
     * 保存
     *
     * @param info
     * @return
     */
    @Override
    public boolean saveElectricityInfo(MesMeterElectricityInfo info) {
        boolean result=false;
        LambdaQueryWrapper<MesMeterElectricityInfo> countWrapper=new LambdaQueryWrapper<>();
        if(null!=info.getId()){
            countWrapper.ne(MesMeterElectricityInfo::getId,info.getId());
        }
        countWrapper.eq(MesMeterElectricityInfo::getElectricityName,info.getElectricityName());
        Long count=count(countWrapper);
        if(count>0){
            throw new ServiceException("该用电名称已存在!");
        }
        if(null!=info.getId()){
            result=updateById(info);
        }else {
            result=save(info);
        }
        return result;
    }

    /**
     * 查看
     *
     * @param infoId
     * @return
     */
    @Override
    public MesMeterElectricityInfo view(Long infoId) {
        MesMeterElectricityInfo info=new MesMeterElectricityInfo();
        info=getById(infoId);
        return info;
    }

    /**
     * 删除
     *
     * @param infoId
     * @return
     */
    @Override
    public boolean delete(Long infoId) {
        LambdaQueryWrapper<MesMeter> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(MesMeter::getElectricityId,infoId);
        Long count=mesMeterService.count(wrapper);
        if(count>0){
            throw new ServiceException("已关联电表，不允许删除");
        }
        MesMeterElectricityInfo info=getById(infoId);
        if(info.getParentId()==0){
            LambdaQueryWrapper<MesMeterElectricityInfo> infoWapper=new LambdaQueryWrapper<>();
            infoWapper.eq(MesMeterElectricityInfo::getParentId,info.getId());
            List<MesMeterElectricityInfo> infoList=list(infoWapper);
            Set<Long> infoIdSet=new HashSet<>();
            if(infoList.size()>0){
                throw new ServiceException("存在子级，请先删除子级！");
            }
        }
        return removeById(infoId);
    }

    /**
     * 获取电表树(带用电类型大分类)
     *
     * @return
     */
    @Override
    public JSONArray getMeterTree() {
        Integer parentId=0;
        Integer electricityType=0;
        MeterTreeItem treeByType = getTreeByType(electricityType, parentId);
        List<MeterTreeItem> data=new ArrayList<>();
        data.add(treeByType);
        electricityType=1;
        treeByType = getTreeByType(electricityType, parentId);
        data.add(treeByType);
        electricityType=2;
        treeByType = getTreeByType(electricityType, parentId);
        data.add(treeByType);
        //List<MesMeter> list = mesMeterService.list();
        JoinLambdaWrapper<MesMeter> joinLambdaWrapper = new JoinLambdaWrapper<>(MesMeter.class);
        joinLambdaWrapper.leftJoin(IotGateway.class, IotGateway::getGatewayDeviceId, MesMeter::getGatewayDeviceId)
                .eq(IotGateway::getIsCreateTable,true).end();
        List<MesMeter> list = mesMeterService.joinList(joinLambdaWrapper, MesMeter.class);
        //查询分类下关联电表Map
        Map<Long,Set<MesMeter>> map=new HashMap<>();
        list.forEach(item->{
            Set<MesMeter> meterSet=new HashSet<>();
            if(map.containsKey(item.getElectricityId())){
                meterSet=map.get(item.getElectricityId());
            }
            meterSet.add(item);
            map.put(item.getElectricityId(),meterSet);
        });
        data.forEach(type->{
            List<MeterTreeItem> childrenType = type.getChildren();
            childrenType.forEach(item->{
                //if(map.containsKey(item.getId())){
                    List<MeterTreeItem> children = item.getChildren();
                    for (MeterTreeItem child : children) {
                        if(map.containsKey(child.getId())){
                            List<MeterTreeItem> childrenMeter = getMeterChildren(child.getId(), map,true);
                            child.setChildren(childrenMeter);
                        }
                    }
                if(map.containsKey(item.getId())) {
                    List<MeterTreeItem> meterChildren = getMeterChildren(item.getId(), map, true);
                    children.addAll(meterChildren);
                }
                //}
            });
        });
        return JSONArray.parseArray(JSON.toJSONString(data));
    }

    public MeterTreeItem getTreeByType(Integer electricityType,Integer parentId){
        String itemName="生产用电";
        if(electricityType==1) {
            itemName="生产辅助用电";
        }
        if(electricityType==2) {
            itemName="非生产用电";
        }
        LambdaQueryWrapper<MesMeterElectricityInfo> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(MesMeterElectricityInfo::getElectricityType,electricityType);
        List<MesMeterElectricityInfo > infoList=list(wrapper);
        List<MeterTreeItem> tree = getChildrenItem(parentId, infoList,electricityType);
        MeterTreeItem treeItem=new MeterTreeItem(-Long.valueOf(electricityType),-Long.valueOf(electricityType*10),itemName);
        treeItem.setChildren(tree);
        return treeItem;
    }

    /**
     * 填充电表
     * @param parentId
     * @param map
     * @param isMeter 是否电表
     * @return
     */
    public  List<MeterTreeItem> getMeterChildren(Long parentId,Map<Long,Set<MesMeter>> map,boolean isMeter){
        List<MeterTreeItem> children =new ArrayList<>();
        Set<MesMeter> meterSet=map.get(parentId);
        for (MesMeter meter : meterSet) {
            MeterTreeItem treeItem=new MeterTreeItem(meter.getId(),parentId,meter.getMeterName(),isMeter,meter.getMeterHistoryTableName());
            children.add(treeItem);
        }
        return children;
    }
    /**
     * 获取树状结构
     *
     * @return
     */
    @Override
    public JSONArray getTree() {
        int parentId=0;
        List<MesMeterElectricityInfo > infoList=list();
        List<MesMeterElectricityInfoVO> tree = getChildren(parentId, infoList);
        return JSONArray.parseArray(JSON.toJSONString(tree));
    }

    /**
     * 获取树
     * @param parentId
     * @param infoList
     * @return
     */
    public List<MesMeterElectricityInfoVO> getChildren(int parentId,List<MesMeterElectricityInfo> infoList){
        List<MesMeterElectricityInfoVO> list = new ArrayList<>();
        /**
         * Optional.ofNullable(menuList).orElse(new ArrayList<>())  如果menuList是空的则返回一个new ArrayList<>()
         *  .stream() 返回List中的流
         *  .filter(menu -> menu.getParentId().equals(parentId)) 筛选List，返回只有条件成立的元素（当前元素的parentId必须等于父id）
         *  .forEach 遍历这个list
         */
        Optional.ofNullable(infoList).orElse(new ArrayList<>())
                .stream()
                .filter(info -> info.getParentId()==parentId)
                .forEach(info -> {
                    MesMeterElectricityInfoVO vo=new MesMeterElectricityInfoVO();
                    BeanUtils.copyProperties(info,vo);
                    List<MesMeterElectricityInfoVO> children=getChildren(info.getId().intValue(),infoList);
                    vo.setChildren(children);
                    list.add(vo);
                });
        return list;
    }
    /**
     * 获取树(不带用电类型分类)
     * @param parentId
     * @param infoList
     * @return
     */
    public List<MeterTreeItem> getChildrenItem(int parentId, List<MesMeterElectricityInfo> infoList){
        List<MeterTreeItem> list = new ArrayList<>();
        Optional.ofNullable(infoList).orElse(new ArrayList<>())
                .stream()
                .filter(info -> info.getParentId()==parentId)
                .forEach(info -> {
                    MeterTreeItem item=new MeterTreeItem(info.getId(),info.getParentId(),info.getElectricityName());
                    List<MeterTreeItem> children=getChildrenItem(info.getId().intValue(),infoList);
                    item.setChildren(children);
                    list.add(item);
                });
        return list;
    }
    /**
     * 获取树
     * @param parentId
     * @param infoList
     * @return
     */
    public List<MeterTreeItem> getChildrenItem(int parentId, List<MesMeterElectricityInfo> infoList,Integer electricityType){
        List<MeterTreeItem> list = new ArrayList<>();
        Optional.ofNullable(infoList).orElse(new ArrayList<>())
                .stream()
                .filter(info -> info.getParentId()==parentId)
                .filter(info -> info.getElectricityType()==electricityType)
                .forEach(info -> {
                    MeterTreeItem item=new MeterTreeItem(info.getId(),info.getParentId(),info.getElectricityName());
                    List<MeterTreeItem> children=getChildrenItem(info.getId().intValue(),infoList,electricityType);
                    item.setChildren(children);
                    list.add(item);
                });
        return list;
    }
}
